home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 June / june_2000.iso / Site Building / JavaNavigator / JavaNavigator.exe / %MAINDIR% / files / JClass / TreeView.class (.txt) < prev    next >
Encoding:
Java Class File  |  2000-05-11  |  21.9 KB  |  1,198 lines

  1. import java.awt.BorderLayout;
  2. import java.awt.Color;
  3. import java.awt.Component;
  4. import java.awt.Container;
  5. import java.awt.Dimension;
  6. import java.awt.Event;
  7. import java.awt.Font;
  8. import java.awt.FontMetrics;
  9. import java.awt.Graphics;
  10. import java.awt.Image;
  11. import java.awt.LayoutManager;
  12. import java.awt.Panel;
  13. import java.awt.Polygon;
  14. import java.awt.Rectangle;
  15. import java.awt.Scrollbar;
  16. import java.util.StringTokenizer;
  17. import java.util.Vector;
  18.  
  19. public class TreeView extends Panel {
  20.    public static final int LEFT = 0;
  21.    public static final int RIGHT = 1;
  22.    // $FF: renamed from: UP int
  23.    public static final int field_0 = 2;
  24.    public static final int DOWN = 3;
  25.    public static final int CHILD = 0;
  26.    public static final int NEXT = 1;
  27.    public static final int LAST = 2;
  28.    private TreeNode rootNode;
  29.    private TreeNode mouseOverNode;
  30.    private TreeNode selectedNode;
  31.    private TreeNode topVisibleNode;
  32.    Scrollbar sbV;
  33.    int sbVPosition;
  34.    int sbVWidth;
  35.    long sbVTimer;
  36.    int count;
  37.    int viewCount;
  38.    private Color bgHighlightColor;
  39.    private Color fgHighlightColor;
  40.    private Color fgMouseOverColor;
  41.    private Color cLineColor;
  42.    private Color cFolderCColor;
  43.    private Color cFolderOColor;
  44.    private Color cLeafColor;
  45.    private Color cToolTipFC;
  46.    private Color cToolTipBC;
  47.    private Color cMouseOverFrame;
  48.    private int viewHeight;
  49.    private int viewWidth;
  50.    private int viewWidest;
  51.    int cellSize;
  52.    int clickSize;
  53.    int imageInset;
  54.    int textInset;
  55.    int textBaseLine;
  56.    // $FF: renamed from: fm java.awt.FontMetrics
  57.    private FontMetrics field_1;
  58.    long timeMouseDown;
  59.    int doubleClickResolution;
  60.    protected Image im1;
  61.    protected Image imgBG;
  62.    // $FF: renamed from: g1 java.awt.Graphics
  63.    protected Graphics field_2;
  64.    private String[] treeStructure;
  65.    int[] xPts;
  66.    int[] yPts;
  67.    int iStep;
  68.    String sStyle;
  69.    String sMouseOver;
  70.    Font fFont;
  71.    String dblClick;
  72.    String sToolTip;
  73.    TreeNode newNode;
  74.    TreeNode oldNode;
  75.    TreeNode oldSNode;
  76.    String flgBorder;
  77.    boolean mouseOver;
  78.    boolean flgToolTip;
  79.    boolean flgMouseOverRect;
  80.    private Polygon poly;
  81.    // $FF: renamed from: e java.util.Vector
  82.    private Vector field_3;
  83.    // $FF: renamed from: v java.util.Vector
  84.    private Vector field_4;
  85.  
  86.    void TreeView_MouseExit(Event event) {
  87.       if (this.oldSNode != null) {
  88.          if (this.flgToolTip) {
  89.             this.flgToolTip = false;
  90.             this.redraw();
  91.          }
  92.  
  93.          this.mouseOver = false;
  94.          this.drawNodeText(this.oldSNode, (this.field_4.indexOf(this.oldSNode) - this.sbVPosition) * this.cellSize, true);
  95.          ((Component)this).repaint();
  96.          this.oldNode = null;
  97.       }
  98.  
  99.    }
  100.  
  101.    public TreeView() {
  102.       this.sbVWidth = 16;
  103.       this.sbVTimer = -1L;
  104.       this.bgHighlightColor = Color.blue;
  105.       this.fgHighlightColor = Color.white;
  106.       this.fgMouseOverColor = Color.red;
  107.       this.cLineColor = Color.black;
  108.       this.cFolderCColor = Color.black;
  109.       this.cFolderOColor = Color.black;
  110.       this.cLeafColor = Color.black;
  111.       this.cToolTipFC = Color.black;
  112.       this.cToolTipBC = Color.yellow;
  113.       this.cMouseOverFrame = Color.red;
  114.       this.viewHeight = 300;
  115.       this.viewWidth = 300;
  116.       this.cellSize = 16;
  117.       this.clickSize = 8;
  118.       this.imageInset = 3;
  119.       this.textInset = 6;
  120.       this.textBaseLine = 3;
  121.       this.doubleClickResolution = 333;
  122.       this.iStep = 3;
  123.       this.sStyle = "AXAA";
  124.       this.sMouseOver = "none";
  125.       this.fFont = new Font("Dialog", 0, 12);
  126.       this.dblClick = "no";
  127.       this.sToolTip = "yes";
  128.       this.mouseOver = false;
  129.       this.flgToolTip = false;
  130.       this.flgMouseOverRect = false;
  131.       super.setLayout(new BorderLayout());
  132.       ((Container)this).add("East", this.sbV = new Scrollbar(1));
  133.       this.sbV.hide();
  134.    }
  135.  
  136.    public TreeView(TreeNode head) {
  137.       this();
  138.       this.selectedNode = this.rootNode = head;
  139.       this.count = 1;
  140.    }
  141.  
  142.    public void setBackground(Color c) {
  143.       super.setBackground(c);
  144.       ((Component)this).invalidate();
  145.    }
  146.  
  147.    public void setStyle(String s) {
  148.       this.sStyle = s;
  149.       ((Component)this).invalidate();
  150.    }
  151.  
  152.    public void setMouseOverStyle(String s) {
  153.       this.sMouseOver = s;
  154.       ((Component)this).invalidate();
  155.    }
  156.  
  157.    public void setNode(String s) {
  158.       this.recount();
  159.  
  160.       for(int i = 0; i < this.count; ++i) {
  161.          TreeNode tn = (TreeNode)this.field_3.elementAt(i);
  162.          if (tn.text != null && s.equals(tn.text)) {
  163.             this.selectedNode = tn;
  164.             if (tn.depth > 0) {
  165.                TreeNode tn1 = tn.parent;
  166.                tn1.expand();
  167.  
  168.                while(tn1.parent != null) {
  169.                   tn1 = tn1.parent;
  170.                   tn1.expand();
  171.                }
  172.  
  173.                tn.parent.expand();
  174.                this.resetVector();
  175.                this.selectedNode = tn;
  176.             }
  177.  
  178.             if (this.viewable(tn)) {
  179.                this.sbVPosition = this.field_4.indexOf(tn);
  180.                this.sbV.setValue(this.sbVPosition);
  181.             }
  182.  
  183.             this.redraw();
  184.          }
  185.       }
  186.  
  187.    }
  188.  
  189.    public void setForeground(Color c) {
  190.       super.setForeground(c);
  191.       ((Component)this).invalidate();
  192.    }
  193.  
  194.    public void setToolTipForeColor(Color c) {
  195.       this.cToolTipFC = c;
  196.       ((Component)this).invalidate();
  197.    }
  198.  
  199.    public void setToolTipBackColor(Color c) {
  200.       this.cToolTipBC = c;
  201.       ((Component)this).invalidate();
  202.    }
  203.  
  204.    public void setFgHilite(Color c) {
  205.       this.fgHighlightColor = c;
  206.       ((Component)this).invalidate();
  207.    }
  208.  
  209.    public void setMouseOverFrameColor(Color c) {
  210.       this.cMouseOverFrame = c;
  211.       ((Component)this).invalidate();
  212.    }
  213.  
  214.    public void setBgHilite(Color c) {
  215.       this.bgHighlightColor = c;
  216.       ((Component)this).invalidate();
  217.    }
  218.  
  219.    public void setMOHilite(Color c) {
  220.       this.fgMouseOverColor = c;
  221.       ((Component)this).invalidate();
  222.    }
  223.  
  224.    public void setLineColor(Color c) {
  225.       this.cLineColor = c;
  226.       ((Component)this).invalidate();
  227.    }
  228.  
  229.    public void setLineStep(int i) {
  230.       this.iStep = i;
  231.       ((Component)this).invalidate();
  232.    }
  233.  
  234.    public void setFolderOColor(Color c) {
  235.       this.cFolderOColor = c;
  236.       ((Component)this).invalidate();
  237.    }
  238.  
  239.    public void setFolderCColor(Color c) {
  240.       this.cFolderCColor = c;
  241.       ((Component)this).invalidate();
  242.    }
  243.  
  244.    public void setLeafColor(Color c) {
  245.       this.cLeafColor = c;
  246.       ((Component)this).invalidate();
  247.    }
  248.  
  249.    public void setBorder(String s) {
  250.       this.flgBorder = s;
  251.       ((Component)this).invalidate();
  252.    }
  253.  
  254.    public void setFont(Font f) {
  255.       if (f != null) {
  256.          this.fFont = f;
  257.       }
  258.  
  259.       ((Component)this).invalidate();
  260.    }
  261.  
  262.    public void setDblClick(String s) {
  263.       this.dblClick = s;
  264.       ((Component)this).invalidate();
  265.    }
  266.  
  267.    public void setToolTip(String s) {
  268.       this.sToolTip = s;
  269.       ((Component)this).invalidate();
  270.    }
  271.  
  272.    public void setBGImage(Image img) {
  273.       this.imgBG = img;
  274.       ((Component)this).invalidate();
  275.    }
  276.  
  277.    public void insert(TreeNode newNode, TreeNode relativeNode, int position, boolean expand) {
  278.       if (newNode != null && relativeNode != null) {
  279.          if (this.exists(relativeNode)) {
  280.             switch (position) {
  281.                case 0:
  282.                   this.addChild(newNode, relativeNode, expand);
  283.                   return;
  284.                case 1:
  285.                   this.addSibling(newNode, relativeNode, expand);
  286.                   return;
  287.                case 2:
  288.                   this.addSibling(newNode, relativeNode, expand);
  289.                   return;
  290.                default:
  291.             }
  292.          }
  293.       }
  294.    }
  295.  
  296.    public TreeNode getRootNode() {
  297.       return this.rootNode;
  298.    }
  299.  
  300.    public TreeNode getMouseOverNode() {
  301.       return this.mouseOverNode;
  302.    }
  303.  
  304.    public int getCount() {
  305.       return this.count;
  306.    }
  307.  
  308.    public int getViewCount() {
  309.       return this.viewCount;
  310.    }
  311.  
  312.    boolean viewable(TreeNode node) {
  313.       for(int i = 0; i < this.viewCount; ++i) {
  314.          if (node == this.field_4.elementAt(i)) {
  315.             return true;
  316.          }
  317.       }
  318.  
  319.       return false;
  320.    }
  321.  
  322.    boolean viewable(String s) {
  323.       if (s == null) {
  324.          return false;
  325.       } else {
  326.          for(int i = 0; i < this.viewCount; ++i) {
  327.             TreeNode tn = (TreeNode)this.field_4.elementAt(i);
  328.             if (tn.text != null && s.equals(tn.text)) {
  329.                return true;
  330.             }
  331.          }
  332.  
  333.          return false;
  334.       }
  335.    }
  336.  
  337.    public boolean exists(TreeNode node) {
  338.       this.recount();
  339.  
  340.       for(int i = 0; i < this.count; ++i) {
  341.          if (node == this.field_3.elementAt(i)) {
  342.             return true;
  343.          }
  344.       }
  345.  
  346.       return false;
  347.    }
  348.  
  349.    public boolean exists(String s) {
  350.       this.recount();
  351.       if (s == null) {
  352.          return false;
  353.       } else {
  354.          for(int i = 0; i < this.count; ++i) {
  355.             TreeNode tn = (TreeNode)this.field_3.elementAt(i);
  356.             if (tn.text != null && s.equals(tn.text)) {
  357.                return true;
  358.             }
  359.          }
  360.  
  361.          return false;
  362.       }
  363.    }
  364.  
  365.    public void append(TreeNode newNode, boolean expand) {
  366.       if (this.rootNode == null) {
  367.          this.rootNode = newNode;
  368.          this.selectedNode = this.rootNode;
  369.          this.count = 1;
  370.       } else {
  371.          this.addSibling(newNode, this.rootNode, expand);
  372.       }
  373.    }
  374.  
  375.    void addChild(TreeNode newNode, TreeNode relativeNode, boolean expand) {
  376.       if (relativeNode.child == null) {
  377.          relativeNode.child = newNode;
  378.          newNode.parent = relativeNode;
  379.          if (expand) {
  380.             relativeNode.expand();
  381.          }
  382.  
  383.          ++this.count;
  384.       } else {
  385.          this.addSibling(newNode, relativeNode.child, expand);
  386.       }
  387.  
  388.       ++relativeNode.numberOfChildren;
  389.    }
  390.  
  391.    void addSibling(TreeNode newNode, TreeNode siblingNode, boolean expand) {
  392.       TreeNode tempNode;
  393.       for(tempNode = siblingNode; tempNode.sibling != null; tempNode = tempNode.sibling) {
  394.       }
  395.  
  396.       tempNode.sibling = newNode;
  397.       newNode.parent = tempNode.parent;
  398.       if (expand) {
  399.          newNode.expand();
  400.       }
  401.  
  402.       ++this.count;
  403.    }
  404.  
  405.    public TreeNode remove(String s) {
  406.       this.recount();
  407.  
  408.       for(int i = 0; i < this.count; ++i) {
  409.          TreeNode tn = (TreeNode)this.field_3.elementAt(i);
  410.          if (tn.text != null && s.equals(tn.text)) {
  411.             this.remove(tn);
  412.             return tn;
  413.          }
  414.       }
  415.  
  416.       return null;
  417.    }
  418.  
  419.    public void removeSelected() {
  420.       if (this.selectedNode != null) {
  421.          this.remove(this.selectedNode);
  422.       }
  423.  
  424.    }
  425.  
  426.    public void remove(TreeNode node) {
  427.       if (this.exists(node)) {
  428.          if (node == this.selectedNode) {
  429.             int index = this.field_4.indexOf(this.selectedNode);
  430.             if (index == -1) {
  431.                index = this.field_3.indexOf(this.selectedNode);
  432.             }
  433.  
  434.             if (index > this.viewCount - 1) {
  435.                index = this.viewCount - 1;
  436.             }
  437.  
  438.             if (index > 0) {
  439.                this.changeSelection((TreeNode)this.field_4.elementAt(index - 1));
  440.             } else if (this.viewCount > 0) {
  441.                this.changeSelection((TreeNode)this.field_4.elementAt(1));
  442.             }
  443.          }
  444.  
  445.          if (node.parent != null) {
  446.             if (node.parent.child == node) {
  447.                if (node.sibling != null) {
  448.                   node.parent.child = node.sibling;
  449.                } else {
  450.                   node.parent.child = null;
  451.                   node.parent.collapse();
  452.                }
  453.             } else {
  454.                TreeNode tn;
  455.                for(tn = node.parent.child; tn.sibling != node; tn = tn.sibling) {
  456.                }
  457.  
  458.                if (node.sibling != null) {
  459.                   tn.sibling = node.sibling;
  460.                } else {
  461.                   tn.sibling = null;
  462.                }
  463.             }
  464.          } else if (node == this.rootNode) {
  465.             if (node.sibling == null) {
  466.                this.rootNode = null;
  467.             } else {
  468.                this.rootNode = node.sibling;
  469.             }
  470.          } else {
  471.             TreeNode tn;
  472.             for(tn = this.rootNode; tn.sibling != node; tn = tn.sibling) {
  473.             }
  474.  
  475.             if (node.sibling != null) {
  476.                tn.sibling = node.sibling;
  477.             } else {
  478.                tn.sibling = null;
  479.             }
  480.          }
  481.  
  482.          this.recount();
  483.       }
  484.    }
  485.  
  486.    private void recount() {
  487.       this.count = 0;
  488.       this.field_3 = new Vector();
  489.       if (this.rootNode != null) {
  490.          this.rootNode.depth = 0;
  491.          this.traverse(this.rootNode);
  492.       }
  493.  
  494.    }
  495.  
  496.    protected void drawToolTip(Graphics g2, int x, int y, String s, FontMetrics fm, Color bc, Color fc) {
  497.       if (this.sToolTip.toLowerCase().equals("yes")) {
  498.          Dimension d = ((Component)this).size();
  499.          if (x + fm.stringWidth(s) > d.width - this.sbVWidth && y > 0) {
  500.             String sWord = "";
  501.             String tmpS = "";
  502.             String tmpS1 = "";
  503.             String tmpS2 = "";
  504.             String tmpS3 = "";
  505.             int pos = 0;
  506.             x = 0;
  507.             pos = s.indexOf(32, pos);
  508.             if (pos == -1) {
  509.                for(int i = 0; i < s.length(); ++i) {
  510.                   if (x + fm.stringWidth(tmpS1) < d.width - (this.sbVWidth + 10)) {
  511.                      tmpS1 = tmpS1 + s.charAt(i);
  512.                   } else {
  513.                      tmpS2 = tmpS2 + s.charAt(i);
  514.                   }
  515.                }
  516.             } else {
  517.                StringTokenizer parser = new StringTokenizer(s.trim(), " ");
  518.  
  519.                while(parser.hasMoreTokens()) {
  520.                   try {
  521.                      sWord = parser.nextToken();
  522.                      if (tmpS.equals("")) {
  523.                         tmpS = sWord;
  524.                      } else {
  525.                         tmpS = tmpS + " " + sWord;
  526.                      }
  527.  
  528.                      if (x + fm.stringWidth(tmpS) > d.width - (this.sbVWidth + 10)) {
  529.                         if (!tmpS1.trim().equals("")) {
  530.                            tmpS2 = tmpS3;
  531.                            break;
  532.                         }
  533.  
  534.                         tmpS1 = tmpS3;
  535.                         tmpS = "";
  536.                         tmpS3 = "";
  537.                      }
  538.  
  539.                      if (tmpS3.equals("")) {
  540.                         tmpS3 = sWord;
  541.                      } else {
  542.                         tmpS3 = tmpS3 + " " + sWord;
  543.                      }
  544.                   } catch (Exception var16) {
  545.                   }
  546.                }
  547.  
  548.                if (!tmpS3.equals("")) {
  549.                   if (tmpS1.trim().equals("")) {
  550.                      tmpS1 = tmpS3;
  551.                   } else {
  552.                      tmpS2 = tmpS3;
  553.                   }
  554.                }
  555.             }
  556.  
  557.             if (y + fm.getHeight() > d.height) {
  558.                y = d.height - fm.getHeight() - 2;
  559.             }
  560.  
  561.             g2.setColor(bc);
  562.             if (tmpS2.equals("")) {
  563.                g2.fillRect(x, y, d.width - 1 - x - this.sbVWidth, fm.getHeight() + 2);
  564.                g2.setColor(fc);
  565.                g2.drawRect(x, y, d.width - 1 - x - this.sbVWidth, fm.getHeight() + 2);
  566.                this.field_2.drawString(tmpS1, x + 5, y + this.cellSize - this.textBaseLine);
  567.             } else {
  568.                g2.fillRect(x, y, d.width - 1 - x - this.sbVWidth, fm.getHeight() * 2 + 2);
  569.                g2.setColor(fc);
  570.                g2.drawRect(x, y, d.width - 1 - x - this.sbVWidth, fm.getHeight() * 2 + 2);
  571.                this.field_2.drawString(tmpS1, x + 5, y + this.cellSize - this.textBaseLine);
  572.                this.field_2.drawString(tmpS2, x + 5, y + fm.getHeight() + this.cellSize - this.textBaseLine);
  573.             }
  574.  
  575.             this.flgToolTip = true;
  576.          }
  577.  
  578.       }
  579.    }
  580.  
  581.    private void traverse(TreeNode node) {
  582.       ++this.count;
  583.       this.field_3.addElement(node);
  584.       if (node.child != null) {
  585.          node.child.depth = node.depth + 1;
  586.          this.traverse(node.child);
  587.       }
  588.  
  589.       if (node.sibling != null) {
  590.          node.sibling.depth = node.depth;
  591.          this.traverse(node.sibling);
  592.       }
  593.  
  594.    }
  595.  
  596.    private void resetVector() {
  597.       this.field_4 = new Vector(this.count);
  598.       this.viewWidest = 30;
  599.       if (this.count < 1) {
  600.          this.viewCount = 0;
  601.       } else {
  602.          this.rootNode.depth = 0;
  603.          this.vectorize(this.rootNode);
  604.          this.viewCount = this.field_4.size();
  605.       }
  606.    }
  607.  
  608.    private void vectorize(TreeNode node) {
  609.       if (node != null) {
  610.          this.field_4.addElement(node);
  611.          if (node.isExpanded()) {
  612.             node.child.depth = node.depth + 1;
  613.             this.vectorize(node.child);
  614.          }
  615.  
  616.          if (node.sibling != null) {
  617.             node.sibling.depth = node.depth;
  618.             this.vectorize(node.sibling);
  619.          }
  620.  
  621.       }
  622.    }
  623.  
  624.    public boolean handleEvent(Event event) {
  625.       if (event.target == this.sbV) {
  626.          if (event.arg == null) {
  627.             return false;
  628.          }
  629.  
  630.          if (this.sbVPosition != (Integer)event.arg) {
  631.             this.sbVPosition = (Integer)event.arg;
  632.             if (this.sbVPosition < 0) {
  633.                this.sbVPosition = 0;
  634.             } else {
  635.                this.redraw();
  636.             }
  637.          }
  638.       }
  639.  
  640.       if (event.target == this && event.id == 505) {
  641.          this.TreeView_MouseExit(event);
  642.          return true;
  643.       } else {
  644.          return super.handleEvent(event);
  645.       }
  646.    }
  647.  
  648.    public boolean mouseMove(Event event, int x, int y) {
  649.       try {
  650.          int index = y / this.cellSize + this.sbVPosition;
  651.          if (index > this.viewCount - 1) {
  652.             if (this.oldSNode != null) {
  653.                this.mouseOver = false;
  654.                this.drawNodeText(this.oldSNode, (this.field_4.indexOf(this.oldSNode) - this.sbVPosition) * this.cellSize, true);
  655.                ((Component)this).repaint();
  656.             }
  657.  
  658.             this.oldNode = null;
  659.             this.mouseOverNode = null;
  660.             this.flgToolTip = false;
  661.             this.redraw();
  662.          }
  663.  
  664.          this.newNode = (TreeNode)this.field_4.elementAt(index);
  665.          if (this.newNode != this.oldNode) {
  666.             if (this.flgToolTip) {
  667.                this.flgToolTip = false;
  668.                this.redraw();
  669.             }
  670.  
  671.             if (this.flgMouseOverRect) {
  672.                this.flgMouseOverRect = false;
  673.                this.redraw();
  674.             }
  675.  
  676.             if (this.oldSNode != null) {
  677.                this.mouseOver = false;
  678.                this.drawNodeText(this.oldSNode, (this.field_4.indexOf(this.oldSNode) - this.sbVPosition) * this.cellSize, true);
  679.             }
  680.  
  681.             this.mouseOver = true;
  682.             this.drawNodeText(this.newNode, (this.field_4.indexOf(this.newNode) - this.sbVPosition) * this.cellSize, true);
  683.             ((Component)this).repaint();
  684.             this.oldNode = this.newNode;
  685.          }
  686.  
  687.          ((Component)this).repaint();
  688.       } catch (Exception var5) {
  689.       }
  690.  
  691.       return super.mouseMove(event, x, y);
  692.    }
  693.  
  694.    public boolean mouseDown(Event event, int x, int y) {
  695.       int index = y / this.cellSize + this.sbVPosition;
  696.       if (index > this.viewCount - 1) {
  697.          this.mouseOverNode = null;
  698.          return false;
  699.       } else {
  700.          TreeNode oldNode = this.selectedNode;
  701.          TreeNode newNode = (TreeNode)this.field_4.elementAt(index);
  702.          int newDepth = newNode.getDepth();
  703.          Rectangle toggleBox = new Rectangle(this.cellSize * newDepth + this.cellSize / 4, (index - this.sbVPosition) * this.cellSize + this.clickSize / 2, this.clickSize, this.clickSize);
  704.          if (toggleBox.inside(x, y)) {
  705.             newNode.toggle();
  706.             this.redraw();
  707.          } else {
  708.             this.changeSelection(newNode);
  709.             if (this.dblClick.toLowerCase().equals("yes")) {
  710.                if (newNode == oldNode && event.when - this.timeMouseDown < (long)this.doubleClickResolution) {
  711.                   newNode.toggle();
  712.                   this.redraw();
  713.                   this.sendActionEvent(event);
  714.                   return false;
  715.                }
  716.  
  717.                this.timeMouseDown = event.when;
  718.                this.redraw();
  719.             } else {
  720.                if (newNode != oldNode || event.when - this.timeMouseDown >= (long)this.doubleClickResolution) {
  721.                   newNode.toggle();
  722.                   this.redraw();
  723.                   this.sendActionEvent(event);
  724.                   return false;
  725.                }
  726.  
  727.                this.timeMouseDown = event.when;
  728.             }
  729.          }
  730.  
  731.          return true;
  732.       }
  733.    }
  734.  
  735.    public boolean keyDown(Event event, int key) {
  736.       int index = this.field_4.indexOf(this.selectedNode);
  737.       switch (key) {
  738.          case 10:
  739.             TreeNode newNode = (TreeNode)this.field_4.elementAt(index);
  740.             this.changeSelection(newNode);
  741.             newNode.toggle();
  742.             this.redraw();
  743.             event.id = 501;
  744.             event.arg = new String(this.selectedNode.getText());
  745.             return false;
  746.          case 1006:
  747.             if (this.selectedNode.isExpanded()) {
  748.                this.selectedNode.toggle();
  749.                this.redraw();
  750.                break;
  751.             }
  752.          case 1004:
  753.             if (index > 0) {
  754.                --index;
  755.                this.changeSelection((TreeNode)this.field_4.elementAt(index));
  756.                this.redraw();
  757.                ((Component)this).requestFocus();
  758.             }
  759.             break;
  760.          case 1007:
  761.             if (this.selectedNode.isExpandable() && !this.selectedNode.isExpanded()) {
  762.                this.selectedNode.toggle();
  763.                this.redraw();
  764.                break;
  765.             } else if (!this.selectedNode.isExpandable()) {
  766.                break;
  767.             }
  768.          case 1005:
  769.             if (index < this.viewCount - 1) {
  770.                ++index;
  771.                this.changeSelection((TreeNode)this.field_4.elementAt(index));
  772.                this.redraw();
  773.                ((Component)this).requestFocus();
  774.             }
  775.       }
  776.  
  777.       return false;
  778.    }
  779.  
  780.    private void sendActionEvent(Event event) {
  781.       int id = event.id;
  782.       Object arg = event.arg;
  783.       event.id = 1001;
  784.       event.arg = new String(this.selectedNode.getText());
  785.       ((Component)this).postEvent(event);
  786.       event.id = id;
  787.       event.arg = arg;
  788.    }
  789.  
  790.    public TreeNode getSelectedNode() {
  791.       return this.selectedNode;
  792.    }
  793.  
  794.    public String getSelectedText() {
  795.       return this.selectedNode == null ? null : this.selectedNode.getText();
  796.    }
  797.  
  798.    private void changeSelection(TreeNode node) {
  799.       if (node != this.selectedNode) {
  800.          TreeNode oldNode = this.selectedNode;
  801.          this.selectedNode = node;
  802.          this.drawNodeText(oldNode, (this.field_4.indexOf(oldNode) - this.sbVPosition) * this.cellSize, true);
  803.          this.drawNodeText(node, (this.field_4.indexOf(node) - this.sbVPosition) * this.cellSize, true);
  804.          int index = this.field_4.indexOf(this.selectedNode);
  805.          if (index < this.sbVPosition) {
  806.             --this.sbVPosition;
  807.             this.sbV.setValue(this.sbVPosition);
  808.             this.redraw();
  809.          } else if (index >= this.sbVPosition + (this.viewHeight - this.cellSize / 2) / this.cellSize) {
  810.             ++this.sbVPosition;
  811.             this.sbV.setValue(this.sbVPosition);
  812.             this.redraw();
  813.          } else {
  814.             ((Component)this).repaint();
  815.          }
  816.       }
  817.    }
  818.  
  819.    public void update(Graphics g) {
  820.       this.paint(g);
  821.    }
  822.  
  823.    public void paint(Graphics g) {
  824.       Dimension d = ((Component)this).size();
  825.       if (d.width == this.viewWidth && d.height == this.viewHeight) {
  826.          if (Beans.isDesignTime()) {
  827.             this.resetVector();
  828.             ((Container)this).layout();
  829.             this.drawTree();
  830.          }
  831.       } else {
  832.          this.redraw();
  833.       }
  834.  
  835.       g.drawImage(this.im1, 0, 0, this);
  836.    }
  837.  
  838.    public void redraw() {
  839.       this.resetVector();
  840.       if (this.viewCount > this.viewHeight / this.cellSize) {
  841.          this.sbV.setValues(this.sbVPosition, this.viewHeight / this.cellSize, 0, this.viewCount - 1);
  842.          this.sbV.setPageIncrement(1);
  843.          this.sbVWidth = 16;
  844.          ((Component)this).getParent().paintAll(((Component)this).getParent().getGraphics());
  845.          this.sbV.show();
  846.          ((Container)this).layout();
  847.       } else {
  848.          this.sbV.hide();
  849.          this.sbVWidth = 0;
  850.          this.sbVPosition = 0;
  851.          ((Container)this).layout();
  852.       }
  853.  
  854.       this.drawTree();
  855.       ((Component)this).repaint();
  856.    }
  857.  
  858.    public void drawTree() {
  859.       Dimension d = ((Component)this).size();
  860.       if (d.width != this.viewWidth || d.height != this.viewHeight || this.field_2 == null) {
  861.          this.im1 = ((Component)this).createImage(d.width, d.height);
  862.          if (this.field_2 != null) {
  863.             this.field_2.dispose();
  864.          }
  865.  
  866.          this.field_2 = this.im1.getGraphics();
  867.          this.viewWidth = d.width;
  868.          this.viewHeight = d.height;
  869.       }
  870.  
  871.       this.field_2.setFont(this.fFont);
  872.       this.setFont(this.fFont);
  873.       this.field_1 = ((Component)this).getFontMetrics(this.fFont);
  874.       this.field_2.setColor(((Component)this).getBackground());
  875.       if (this.imgBG != null) {
  876.          for(int x = 0; x < d.width; x += this.imgBG.getWidth(this)) {
  877.             for(int i = 0; i < d.height; i += this.imgBG.getHeight(this)) {
  878.                this.field_2.drawImage(this.imgBG, x, i, this.imgBG.getWidth(this), this.imgBG.getHeight(this), Color.black, this);
  879.             }
  880.          }
  881.  
  882.          ((Component)this).repaint();
  883.       } else {
  884.          this.field_2.fillRect(0, 0, this.viewWidth, this.viewHeight);
  885.       }
  886.  
  887.       int lastOne = this.sbVPosition + this.viewHeight / this.cellSize;
  888.       if (lastOne > this.viewCount) {
  889.          lastOne = this.viewCount;
  890.       }
  891.  
  892.       for(int i = this.sbVPosition; i < lastOne; ++i) {
  893.          TreeNode node = (TreeNode)this.field_4.elementAt(i);
  894.          int x = this.cellSize * (node.depth + 1);
  895.          int y = (i - this.sbVPosition) * this.cellSize;
  896.          if (this.sStyle.charAt(2) != 'X') {
  897.             this.field_2.setColor(((Component)this).getForeground());
  898.             if (node.sibling != null) {
  899.                int k = this.field_4.indexOf(node.sibling) - i;
  900.                if (k > lastOne) {
  901.                   k = lastOne;
  902.                }
  903.  
  904.                this.drawDotLine(x - this.cellSize / 2, y + this.cellSize / 2, x - this.cellSize / 2, y + this.cellSize / 2 + k * this.cellSize);
  905.             }
  906.  
  907.             for(int m = 0; m < i; ++m) {
  908.                TreeNode sib = (TreeNode)this.field_4.elementAt(m);
  909.                if (sib.sibling == node && m < this.sbVPosition) {
  910.                   this.drawDotLine(x - this.cellSize / 2, 0, x - this.cellSize / 2, y + this.cellSize / 2);
  911.                }
  912.             }
  913.  
  914.             if (node.isExpanded()) {
  915.                this.drawDotLine(x + this.cellSize / 2, y + this.cellSize, x + this.cellSize / 2, y + this.cellSize + this.cellSize / 2);
  916.             }
  917.  
  918.             this.field_2.setColor(((Component)this).getForeground());
  919.             this.drawDotLine(x - this.cellSize / 2, y + this.cellSize / 2, x + this.cellSize / 2, y + this.cellSize / 2);
  920.          }
  921.  
  922.          if (this.sStyle.charAt(0) == 'A') {
  923.             if (node.isExpandable()) {
  924.                this.field_2.setColor(((Component)this).getBackground());
  925.                this.field_2.fillRect(this.cellSize * node.depth + this.cellSize / 4, y + this.clickSize / 2, this.clickSize, this.clickSize);
  926.                this.field_2.setColor(this.cLineColor);
  927.                this.field_2.drawRect(this.cellSize * node.depth + this.cellSize / 4, y + this.clickSize / 2, this.clickSize, this.clickSize);
  928.                this.field_2.drawLine(this.cellSize * node.depth + this.cellSize / 4 + 2, y + this.cellSize / 2, this.cellSize * node.depth + this.cellSize / 4 + this.clickSize - 2, y + this.cellSize / 2);
  929.                if (!node.isExpanded()) {
  930.                   this.field_2.drawLine(this.cellSize * node.depth + this.cellSize / 2, y + this.clickSize / 2 + 2, this.cellSize * node.depth + this.cellSize / 2, y + this.clickSize / 2 + this.clickSize - 2);
  931.                }
  932.             }
  933.          } else if (node.isExpandable()) {
  934.             this.xPts = new int[4];
  935.             this.yPts = new int[4];
  936.             if (!node.isExpanded()) {
  937.                if (this.sStyle.charAt(0) == 'E' || this.sStyle.charAt(0) == 'F') {
  938.                   this.field_2.setColor(this.cFolderCColor);
  939.                   this.xPts[0] = this.cellSize * node.depth + this.cellSize / 4 + 1;
  940.                   this.xPts[1] = this.cellSize * node.depth + this.cellSize / 4 + this.clickSize;
  941.                   this.xPts[2] = this.cellSize * node.depth + this.cellSize / 4 + 1;
  942.                   this.xPts[3] = this.cellSize * node.depth + this.cellSize / 4 + 1;
  943.                   this.yPts[0] = y + 1;
  944.                   this.yPts[1] = y + this.cellSize / 2;
  945.                   this.yPts[2] = y + this.cellSize - 1;
  946.                   this.yPts[3] = y + 1;
  947.                   this.poly = new Polygon(this.xPts, this.yPts, this.xPts.length);
  948.                   this.field_2.fillPolygon(this.poly);
  949.                }
  950.  
  951.                if (this.sStyle.charAt(0) == 'B' || this.sStyle.charAt(0) == 'C' || this.sStyle.charAt(0) == 'D') {
  952.                   this.field_2.setColor(this.cFolderCColor);
  953.                   this.field_2.fillRect(this.cellSize * node.depth + this.cellSize / 4, y + this.clickSize / 2, this.clickSize + 2, this.clickSize + 2);
  954.                }
  955.             } else {
  956.                if (this.sStyle.charAt(0) == 'C' || this.sStyle.charAt(0) == 'E') {
  957.                   this.field_2.setColor(this.cFolderOColor);
  958.                   this.xPts[0] = this.cellSize * node.depth + this.cellSize / 4 - 2;
  959.                   this.xPts[1] = this.cellSize * node.depth + this.cellSize / 4 - 2 + this.clickSize + 2;
  960.                   this.xPts[2] = this.cellSize * node.depth + this.cellSize / 4 - 2 + (this.clickSize + 2) / 2;
  961.                   this.xPts[3] = this.cellSize * node.depth + this.cellSize / 4 - 2;
  962.                   this.yPts[0] = y + 3;
  963.                   this.yPts[1] = y + 3;
  964.                   this.yPts[2] = y + this.cellSize - 3;
  965.                   this.yPts[3] = y + 3;
  966.                   this.poly = new Polygon(this.xPts, this.yPts, this.xPts.length);
  967.                   this.field_2.fillPolygon(this.poly);
  968.                }
  969.  
  970.                if (this.sStyle.charAt(0) == 'D' || this.sStyle.charAt(0) == 'F') {
  971.                   this.field_2.setColor(this.cFolderOColor);
  972.                   this.xPts[0] = this.cellSize * node.depth + this.cellSize / 4 - 2 + (this.clickSize + 2) / 2;
  973.                   this.xPts[1] = this.cellSize * node.depth + this.cellSize / 4 - 2 + this.clickSize + 2;
  974.                   this.xPts[2] = this.cellSize * node.depth + this.cellSize / 4 - 2;
  975.                   this.xPts[3] = this.cellSize * node.depth + this.cellSize / 4 - 2 + (this.clickSize + 2) / 2;
  976.                   this.yPts[0] = y + 3;
  977.                   this.yPts[1] = y + this.cellSize - 3;
  978.                   this.yPts[2] = y + this.cellSize - 3;
  979.                   this.yPts[3] = y + 3;
  980.                   this.poly = new Polygon(this.xPts, this.yPts, this.xPts.length);
  981.                   this.field_2.fillPolygon(this.poly);
  982.                }
  983.  
  984.                if (this.sStyle.charAt(0) == 'B') {
  985.                   this.field_2.setColor(this.cFolderOColor);
  986.                   this.xPts[0] = this.cellSize * node.depth + this.cellSize / 4 + 1;
  987.                   this.xPts[1] = this.cellSize * node.depth + this.cellSize / 4 + this.clickSize;
  988.                   this.xPts[2] = this.cellSize * node.depth + this.cellSize / 4 + 1;
  989.                   this.xPts[3] = this.cellSize * node.depth + this.cellSize / 4 + 1;
  990.                   this.yPts[0] = y + 1;
  991.                   this.yPts[1] = y + this.cellSize / 2;
  992.                   this.yPts[2] = y + this.cellSize - 1;
  993.                   this.yPts[3] = y + 1;
  994.                   this.poly = new Polygon(this.xPts, this.yPts, this.xPts.length);
  995.                   this.field_2.fillPolygon(this.poly);
  996.                }
  997.             }
  998.          } else if (this.sStyle.charAt(1) == 'A') {
  999.             this.field_2.setColor(this.cLeafColor);
  1000.             this.field_2.fillRect(this.cellSize * node.depth + this.cellSize / 4, y + this.clickSize / 2, this.clickSize, this.clickSize);
  1001.          }
  1002.  
  1003.          Image nodeImage = node.getImage();
  1004.          if (this.sStyle.charAt(3) == 'A') {
  1005.             if (this.sStyle.charAt(0) != 'X' && this.sStyle.charAt(2) == 'X') {
  1006.                --x;
  1007.             }
  1008.  
  1009.             if (this.sStyle.charAt(2) == 'X' && this.sStyle.charAt(0) == 'X') {
  1010.                x -= 10;
  1011.             }
  1012.  
  1013.             if (nodeImage != null) {
  1014.                this.field_2.drawImage(nodeImage, x + this.imageInset, y, this);
  1015.             }
  1016.          }
  1017.  
  1018.          if (node.text != null) {
  1019.             this.drawNodeText(node, y, node == this.selectedNode);
  1020.          }
  1021.       }
  1022.  
  1023.       if (this.flgBorder.toLowerCase().equals("yes")) {
  1024.          this.field_2.setColor(((Component)this).getForeground());
  1025.          this.field_2.drawRect(0, 0, this.viewWidth - this.sbVWidth - 1, this.viewHeight - 1);
  1026.       }
  1027.  
  1028.    }
  1029.  
  1030.    private void drawNodeText(TreeNode node, int yPosition, boolean eraseBackground) {
  1031.       int depth = node.depth;
  1032.       int textOffset = (depth + 1) * this.cellSize + this.cellSize + this.textInset;
  1033.       if (this.sStyle.charAt(3) != 'A') {
  1034.          textOffset -= 15;
  1035.          if (this.sStyle.charAt(2) == 'X') {
  1036.             textOffset -= 5;
  1037.          }
  1038.       } else if (this.sStyle.charAt(0) == 'X' && this.sStyle.charAt(2) == 'X') {
  1039.          textOffset -= 5;
  1040.       }
  1041.  
  1042.       Color fg;
  1043.       if (node == this.selectedNode) {
  1044.          fg = this.fgHighlightColor;
  1045.          Color bg = this.bgHighlightColor;
  1046.          this.mouseOverNode = node;
  1047.          if (eraseBackground) {
  1048.             this.field_2.setColor(bg);
  1049.             this.field_2.fillRect(textOffset - 1, yPosition + 1, this.field_1.stringWidth(node.text) + 4, this.cellSize - 1);
  1050.          }
  1051.       } else {
  1052.          fg = ((Component)this).getForeground();
  1053.          Color bg = ((Component)this).getBackground();
  1054.          if (this.mouseOver) {
  1055.             fg = this.fgMouseOverColor;
  1056.             this.mouseOverNode = node;
  1057.             this.oldSNode = node;
  1058.          }
  1059.       }
  1060.  
  1061.       this.field_2.setColor(fg);
  1062.       this.field_2.drawString(node.text, textOffset, yPosition + this.cellSize - this.textBaseLine);
  1063.       if (this.mouseOver) {
  1064.          if (this.sMouseOver.toLowerCase().equals("rect")) {
  1065.             this.field_2.setColor(this.cMouseOverFrame);
  1066.             this.field_2.drawRect(textOffset - 1, yPosition + 1, this.field_1.stringWidth(node.text) + 1, this.cellSize - 1);
  1067.             this.flgMouseOverRect = true;
  1068.          }
  1069.  
  1070.          if (this.sMouseOver.toLowerCase().equals("line")) {
  1071.             this.field_2.setColor(this.cMouseOverFrame);
  1072.             this.field_2.drawRect(textOffset - 1, yPosition + 1 + this.field_1.getHeight(), this.field_1.stringWidth(node.text) + 1, 1);
  1073.             this.flgMouseOverRect = true;
  1074.          }
  1075.  
  1076.          this.drawToolTip(this.field_2, textOffset - 1, yPosition + 1, node.text, this.field_1, this.cToolTipBC, this.cToolTipFC);
  1077.          this.mouseOver = false;
  1078.       }
  1079.  
  1080.    }
  1081.  
  1082.    private void drawDotLine(int x0, int y0, int x1, int y1) {
  1083.       this.field_2.setColor(this.cLineColor);
  1084.       int iStep1;
  1085.       if (this.sStyle.charAt(2) == 'A') {
  1086.          iStep1 = this.iStep;
  1087.       } else {
  1088.          iStep1 = 1;
  1089.       }
  1090.  
  1091.       if (y0 == y1) {
  1092.          for(int i = x0; i < x1; i += iStep1) {
  1093.             this.field_2.drawLine(i, y0, i, y1);
  1094.          }
  1095.  
  1096.       } else {
  1097.          for(int i = y0; i < y1; i += iStep1) {
  1098.             this.field_2.drawLine(x0, i, x1, i);
  1099.          }
  1100.  
  1101.       }
  1102.    }
  1103.  
  1104.    public void setTreeStructure(String[] s) {
  1105.       this.rootNode = this.selectedNode = this.topVisibleNode = null;
  1106.       this.treeStructure = s;
  1107.  
  1108.       try {
  1109.          this.parseTreeStructure();
  1110.       } catch (InvalidTreeNodeException e) {
  1111.          System.out.println(e);
  1112.       }
  1113.    }
  1114.  
  1115.    public String[] getTreeStructure() {
  1116.       return this.treeStructure;
  1117.    }
  1118.  
  1119.    private void parseTreeStructure() throws InvalidTreeNodeException {
  1120.       String[] tempStructure = null;
  1121.       String entry = null;
  1122.       tempStructure = this.treeStructure;
  1123.       entry = tempStructure[0];
  1124.       if (this.findLastPreSpace(entry) > -1) {
  1125.          throw new InvalidTreeNodeException();
  1126.       } else {
  1127.          TreeNode node = new TreeNode(entry.trim());
  1128.          node.setDepth(0);
  1129.          this.append(node, false);
  1130.  
  1131.          for(int i = 1; i < tempStructure.length; ++i) {
  1132.             entry = tempStructure[i];
  1133.             int indentLevel = this.findLastPreSpace(entry);
  1134.             if (indentLevel == -1) {
  1135.                throw new InvalidTreeNodeException();
  1136.             }
  1137.  
  1138.             TreeNode currentNode = this.rootNode;
  1139.  
  1140.             for(int j = 0; j < indentLevel; ++j) {
  1141.                int numberOfChildren = currentNode.numberOfChildren;
  1142.                TreeNode tempNode = null;
  1143.                if (numberOfChildren > 0) {
  1144.                   for(tempNode = currentNode.child; tempNode.sibling != null; tempNode = tempNode.sibling) {
  1145.                   }
  1146.                }
  1147.  
  1148.                if (tempNode == null) {
  1149.                   break;
  1150.                }
  1151.  
  1152.                currentNode = tempNode;
  1153.             }
  1154.  
  1155.             int diff = indentLevel - currentNode.getDepth();
  1156.             if (diff > 1) {
  1157.                throw new InvalidTreeNodeException();
  1158.             }
  1159.  
  1160.             node = new TreeNode(entry.trim());
  1161.             node.setDepth(indentLevel);
  1162.             if (diff == 1) {
  1163.                this.insert(node, currentNode, 0, false);
  1164.             } else {
  1165.                this.insert(node, currentNode, 1, false);
  1166.             }
  1167.          }
  1168.  
  1169.       }
  1170.    }
  1171.  
  1172.    private int findLastPreSpace(String s) {
  1173.       int length = s.length();
  1174.       if (s.charAt(0) != ' ') {
  1175.          return -1;
  1176.       } else {
  1177.          for(int i = 1; i < length; ++i) {
  1178.             if (s.charAt(i) != ' ') {
  1179.                return i;
  1180.             }
  1181.          }
  1182.  
  1183.          return -1;
  1184.       }
  1185.    }
  1186.  
  1187.    public synchronized Dimension preferredSize() {
  1188.       return new Dimension(175, 125);
  1189.    }
  1190.  
  1191.    public synchronized Dimension minimumSize() {
  1192.       return new Dimension(50, 50);
  1193.    }
  1194.  
  1195.    public void setLayout(LayoutManager lm) {
  1196.    }
  1197. }
  1198.